package util.resource;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import org.newdawn.slick.Font;
import org.newdawn.slick.Image;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.font.effects.ColorEffect;

/**
 * Singleton resource manager. Probably the easiest way to do things-- load all resources once on game startup to
 * minimize the latency of loading a resource from the disk during the middle of a level.
 * @author Logan
 */
public class ResourceManager
{
	public static final String IMAGE_LOCATION="dat/img";
	public static final String FONT_LOCATION="dat/fnt";
			
	public static ResourceManager manager=new ResourceManager();
	
	/**
	 * Gets an image for drawing.
	 * @param imageName - relative path from img/ of image to receive.
	 * @return loaded image
	 */
	public static Image getImage(String imageName)
	{
		Image image=ResourceManager.get().imageMap.get(imageName);
		if(image==null)
			throw new RuntimeException("Image '"+imageName+"' does not exist!");
		return image;
	}
	
	/**
	 * Gets a font for drawing.
	 * @param fontName - the name of the font to request.
	 * @return loaded font
	 */
	public static Font getFont(String fontName)
	{
		Font font=ResourceManager.get().fontMap.get(fontName);
		if(font==null)
			throw new RuntimeException("Font '"+fontName+"' does not exist!");
		return font;
	}
	
	/**
	 * Adds a ResourceListener to be notified of the loading process.
	 * @param l - listener to add.
	 */
	public static void addResourceListener(ResourceListener l)
	{
		ResourceManager.get().addResourceListenerPrivate(l);
	}
	
	/**
	 * Called to load all of the resources.
	 */
	public static void load()
	{
		ResourceManager.get().loadPrivate();
	}
	
	
	//From here on down are just private methods and fields.
	
	private HashMap<String,Image> imageMap;
	private HashMap<String,Font> fontMap;
	
	private ArrayList<ResourceListener> listeners;
	
	private ResourceManager()
	{
		imageMap=new HashMap<String,Image>();
		fontMap=new HashMap<String,Font>();
		listeners=new ArrayList<ResourceListener>();
	}
	
	@SuppressWarnings("unchecked")
	private void loadPrivate()
	{
		int max=0; //number of resources to load
		int current=0; //number of resources loaded
		
		try
		{
			//Load file locations
			ArrayList<File> fileListImages=FileLocator.getFileLocations(IMAGE_LOCATION,".png",true);
			max+=fileListImages.size();
			
			//Load images
			for(File file:fileListImages)
			{
				String currentPath=new File(IMAGE_LOCATION).getAbsolutePath();
				String name=file.getAbsolutePath().substring(currentPath.length()+1);
				Image image=new Image(file.getAbsolutePath());
				image.setFilter(Image.FILTER_NEAREST);
				imageMap.put(name,image);
				
				current+=1;
				for(ResourceListener l:listeners)
					l.resourceLoadedEvent(current,max,name);
			}
			
			//Load fonts
			{
				BufferedReader br=new BufferedReader(new FileReader(ResourceManager.FONT_LOCATION+"/fonts.txt"));
				String line;
				while((line=br.readLine())!=null)
				{
					if(!line.startsWith("#") && line.length()!=0)
					{
						String[] args=line.split(" ");
						if(args.length==5)
						{
							UnicodeFont font=new UnicodeFont(ResourceManager.FONT_LOCATION+"/"+args[1],
									Integer.parseInt(args[2]),args[3].equals("true"),args[4].equals("true"));
							font.addNeheGlyphs();
							//reason for suppressed warnings-- it's a slick problem
							font.getEffects().add(new ColorEffect(java.awt.Color.BLACK));
							
							font.loadGlyphs();
							fontMap.put(args[0],font);
						}
					}
				}
			}
			
			//Tell listeners that we are finished
			for(ResourceListener l:listeners)
				l.doneLoadingEvent();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	private void addResourceListenerPrivate(ResourceListener l)
	{
		listeners.add(l);
	}
	
	private static ResourceManager get()
	{
		return manager;
	}
}
